/*
   虚表设计器
*/
(function ($) {
    $.fn.yqVirtualEdit = function (opts, param) {
        if (typeof opts == 'string') {
            return $.fn.yqVirtualEdit.methods[opts](this, param);
        }

        return this.each(function () {
            $this = $(this);
            var opt;
            if ($this.data("yqtype") == "yqVirtualEdit") {
                var $uniqueID = $this.attr("ID");
                opt = $.extend(options($this), opts);
                destroy($this);
                $this = $("#" + $uniqueID);
            }
            else {
                opt = $.extend({}, $.fn.yqVirtualEdit.defaults, opts);
                var $uniqueID = $this.attr("ID");
                if ($uniqueID === undefined || $uniqueID === null || $uniqueID == "") {
                    $uniqueID = $.getUniqueID();
                    $this.attr("ID", $uniqueID);
                }
            }

            if (opt.width === undefined && $this.width() > 0) {
                opt.width = $this.width();
            }
            else if (typeof opt.width != "undefined") {
                $this.width(opt.width);
            }

            if (opt.height === undefined && $this.height() > 0) {
                opt.height = $this.height();
            }
            else if (typeof opt.height != "undefined") {
                $this.height(opt.height);
            }

            $this.empty();
            opt.node_id = 0;

            opt.ui_load = false;


            //变量信息
            $this.data("virtualedit_opt", opt);
            $this.data("yqtype", "yqVirtualEdit");

            init_ui($this);
        });
    };

    $.fn.yqVirtualEdit.defaults = {
        ui_type: 15,
        ui_mask: {},
        param: {
            titles: [],
            model: []
        },
        isEdit: true,
    };

    $.fn.yqVirtualEdit.methods = {
        options: function (jq) {
            return options($(jq[0]));
        },
        getValue: function (jq) {
            return getValue($(jq[0]));
        },
        setValue: function (jq, value) {
            setValue($(jq[0]), value);
        },
        clear: function (jq) {
            var opt = options($(jq[0]));
            setValue($(jq[0]), {
                ui_type: opt.ui_type,
                ui_mask: {},
                titles: {
                    titles: [],
                    model: []
                }
            });
        },
        resize: function (jq, params) {
            resize($(jq[0]), params);
        },
        destroy: function (jq) {
            destroy($(jq[0]));
        },
    };

    function options($object) {
        return $object.data("virtualedit_opt");
    }

    function init_ui($object) {
        var opt = options($object);
        var $uniqueID = $object.attr("ID");

        var r_width = opt.width - 300;
        if (r_width < 580) {
            r_width = 580;
        }
        var l_width = opt.width - r_width;
        if (l_width < 50) {
            l_width = 50;
        }

        opt.$layout = $object.layout({});
        opt.$layout.layout('add', {
            region: 'west',
            width: l_width,
            split: true
        });

        opt.$layout.layout('add', {
            region: 'center'
        });

        opt.$west = opt.$layout.layout('panel', 'west');
        opt.$center = opt.$layout.layout('panel', 'center');
        opt.$west.append(`
    <select id="`+ $uniqueID + `_s_type" style="width: 240px;"></select>
    <div id="`+ $uniqueID + `_s_div">
        <ul id="`+ $uniqueID + `_s_tree"></ul>
    </div>
`);

        opt.$tabs = opt.$center.tabs({
            border: false,
            tabPosition: 'bottom'
        });
        opt.$tabs_edit = opt.$tabs.tabs('add', {
            title: 'edit',
            selected: true,
            content: `<div style="padding: 1px 0 0 4px;">
    <input id="`+ $uniqueID + `_ui_type" type="text" style="width:80px">
    <input id="`+ $uniqueID + `_ui_title" type="text" style="width:80px">
    <input id="`+ $uniqueID + `_ui_name" type="text" style="width:80px">
    <a id="`+ $uniqueID + `_btn_save" href="#">保存配置</a>
   
</div>
<div id="`+ $uniqueID + `_titles">
</div>
`
        });
        opt.$tabs.tabs("getTab", 0).panel("body").css({ "border-width": 0, "overflow": "hidden" });

        opt.$tabs_json = opt.$tabs.tabs('add', {
            title: 'json',
            selected: false,
            content: `<div id="` + $uniqueID + `_jsonview"></div>`
        });
        opt.$tabs.tabs("getTab", 1).panel("body").css({ "border-width": 0, "overflow": "hidden" });
        $("#" + $uniqueID + "_jsonview").yqCodeEdit({
            types: ["json"],
            isEdit: false,
            type: "json",
            value: "{}",
            goDocEnd: false,
        });

        opt.$tabs_test = opt.$tabs.tabs('add', {
            title: 'test',
            selected: false,
            content: `<div id="` + $uniqueID + `_test"></div>`
        });
        opt.$tabs.tabs("getTab", 2).panel("body").css({ "border-width": 0 });
        $("#" + $uniqueID + "_test").yqUnitEdit({});

        opt.$s_type = $("#" + $uniqueID + "_s_type");
        opt.$div = $("#" + $uniqueID + "_s_div");
        opt.$tree = $("#" + $uniqueID + "_s_tree");
        opt.$table = $("#" + $uniqueID + "_titles");
        opt.$save = $("#" + $uniqueID + "_btn_save");
        opt.$txt_type = $("#" + $uniqueID + "_ui_type");
        opt.$txt_title = $("#" + $uniqueID + "_ui_title");
        opt.$txt_name = $("#" + $uniqueID + "_ui_name");

        opt.$s_type.combobox({
            data: [{
                "id": 17,
                "text": "Attr 属性",
                "selected": true
            }, {
                "id": 15,
                "text": "Table 表格"
            }, {
                "id": 16,
                "text": "Tree 树"
            }],
            valueField: 'id',
            textField: 'text',
            icons: [{
                iconCls: 'yqwin-combo-btn-icon fa fa-pencil-square',
                handler: function (e) {
                    opt.$s_type.combobox("hidePanel");

                    e.preventDefault();
                    var pp = opt.$s_type.next('span.textbox');
                    var prevent_e = $.getPreventDefault(pp[0]);
                    prevent_e.id = $uniqueID;
                    prevent_e.options = opt;
                    var mdiinfo = $.yqGetWindParams();

                    var run_opt = {
                        mdiinfo: mdiinfo,
                        prevent_e: prevent_e,
                        width: 500,
                        height: 400,
                        ui_type: parseInt(opt.$s_type.combobox("getValue")),
                        isEdit: opt.isEdit,
                        treeEdit: true,
                        callback: function (value) {
                            opt.ui_mask = value;
                            tabsChange($object);
                        }
                    };

                    //console.log("setValue",opt.ui_mask);
                    if (opt.ui_mask.blank === undefined) {
                        opt.ui_mask.blank = true;
                    }
                    run_opt.value = opt.ui_mask;

                    if (window.top == window.self) {
                        $.yqUiMaskPopEdit(run_opt);
                    }
                    else {
                        window.top.$.yqUiMaskPopEdit(run_opt);
                    }
                }
            }],
            onChange: function (newValue, oldValue) {
                if (opt.ui_load == false) {
                    return;
                }
                opt.ui_type =parseInt(newValue);
                tabsChange($object);
            }
        });

        var $icon0 = opt.$s_type.combobox("getIcon", 0);
        var $icon1 = opt.$s_type.combobox("getIcon", 1);
        $icon0.before($icon1);

        opt.$s_type.combobox("setValue", opt.ui_type);

        opt.$s_type.next().css({ "margin": "2px" });

        opt.$table.yqTitlesEdit({
            width: 900,
            height: 700,
            isEdit: opt.isEdit,
            treeEdit: true,
            data: {},
        });

        opt.$txt_type.textbox({
            label: "ui_type",
            labelWidth: 55,
            width: 150,
            height: 25,
            readonly: true
        });
        opt.$txt_title.textbox({
            label: "ui_title",
            labelWidth: 55,
            width: 150,
            height: 25,
            readonly: true
        });
        opt.$txt_name.textbox({
            label: "name",
            labelWidth: 45,
            width: 150,
            height: 25,
            readonly: true
        });

        var rootnode = getData($object);

        opt.$tree.tree({
            data: rootnode,
            onSelect: function (node) {
                //console.log(node);
                ui_type = "";
                if (node.id == 0) {
                    ui_type = "root";
                }
                else {
                    switch (node.title.ui_type) {
                        case 1:
                            ui_type = "label"
                            break;
                        case 2:
                            ui_type = "TextBox"
                            break;
                        case 3:
                            ui_type = "Checkbox"
                            break;
                        case 4:
                            ui_type = "DateTimePicker"
                            break;
                        case 5:
                            ui_type = "RichTextBox"
                            break;
                        case 6:
                            ui_type = "ComboBox"
                            break;
                        case 7:
                            ui_type = "ForeignKey"
                            break;
                        case 8:
                            ui_type = "TreeSelect"
                            break;
                        case 9:
                            ui_type = "NumberBox"
                            break;
                        case 10:
                            ui_type = "NumberSpinner"
                            break;
                        case 11:
                            ui_type = "TimeSpinner"
                            break;
                        case 12:
                            ui_type = "DateTimeBox"
                            break;
                        case 13:
                            ui_type = "NCheckBox"
                            break;
                        case 14:
                            ui_type = "NForeignKey"
                            break;
                        case 15:
                            ui_type = "table"
                            break;
                        case 16:
                            ui_type = "Tree"
                            break;
                        case 17:
                            ui_type = "Attr"
                            break;
                        case 18:
                            ui_type = "File"
                            break;
                        case 19:
                            ui_type = "Html/MD"
                            break;
                        default:
                            ui_type = "";
                    }
                }

                opt.$txt_type.textbox("setValue", ui_type);
                opt.$txt_title.textbox("setValue", node.title.ui_title);
                opt.$txt_name.textbox("setValue", node.title.name);
                if (node.title.ui_type == 15 || node.title.ui_type == 16 || node.title.ui_type == 17) {
                    var titles = nodeToTitles(node.children);
                    var model = [];
                    if (typeof node.title.ui_mask.param.model == "object") {
                        model = node.title.ui_mask.param.model;
                    }
                    opt.$table.yqTitlesEdit("isEdit", opt.isEdit);
                    opt.$table.yqTitlesEdit("setValue", { titles: titles, model: model });
                } else {
                    opt.$table.yqTitlesEdit("isEdit", false);
                    opt.$table.yqTitlesEdit("clear");
                    opt.$table.yqTitlesEdit("setUiMaskValue", {
                        ui_type: node.title.ui_type,
                        value: node.title.ui_mask,
                        isEdit: opt.isEdit
                    });
                }

                if (opt.isEdit) {
                    opt.$save.linkbutton("enable");
                } else {
                    opt.$save.linkbutton("disable");
                }

            }, onLoadSuccess: function (node, data) {
                if (opt.ui_load == false) {
                    opt.ui_load = true;

                    opt.$west.panel("options").onResize = function (width, height) {
                        if (opt.setResizeTime === undefined) {
                            opt.setResizeTime = setTimeout(function () {
                                resize($object);
                            }, 100);
                        }
                    }

                    opt.$save.linkbutton({
                        iconCls: 'yqwin-btn-icon fa fa-floppy-o',
                        onClick: function () {
                            var s_node = opt.$tree.tree("getSelected");
                            if (s_node.title.ui_type == 15 ||
                                s_node.title.ui_type == 16 ||
                                s_node.title.ui_type == 17) {
                                var value = opt.$table.yqTitlesEdit("getValue");

                                var nodes = toNodes($object, value);
                                for (let i = s_node.children.length - 1; i >= 0; i--) {
                                    var n = opt.$tree.tree('find', s_node.children[i].id);
                                    opt.$tree.tree("remove", n.target);
                                }

                                opt.$tree.tree("append", {
                                    parent: s_node.target,
                                    data: nodes
                                });

                                var title = s_node.title;
                                title.ui_mask.param.model = value.model;

                                opt.$tree.tree("expand", s_node.target);
                            } else {
                                s_node.title.ui_mask = opt.$table.yqTitlesEdit("getUiMaskValue");
                            }
                        }
                    });
                }
                if (data.length > 0) {
                    //找到第一个元素
                    var n = $(this).tree('find', data[0].id);
                    //调用选中事件
                    $(this).tree('select', n.target);
                }
            },
        });

        resize($object);
        opt.$tabs.tabs("options").onSelect = function (title, index) {
            resize($object);
            tabsChange($object);
        };
    }

    function tabsChange($object) {
        var opt = options($object);
        var $uniqueID = $object.attr("id");
        var tab = opt.$tabs.tabs('getSelected');
        var tab_index = opt.$tabs.tabs('getTabIndex', tab);
        if (tab_index == 1) {
            var value = getValue($object);
            $("#" + $uniqueID + "_jsonview").yqCodeEdit("setValue", $.jsonFormat(value));
        } else if (tab_index == 2) {
            var value = getValue($object);
            var rw = opt.$center.width();
            $("#" + $uniqueID + "_test").yqUnitEdit({
                width: rw,
                height: opt.height - 36,
                ui_mask: value
            });
        }
    }

    function getData($object) {
        var opt = options($object);
        var nodes = toNodes($object, opt.param);

        var ui_mask = $.extend({}, opt.ui_mask);
        ui_mask.param = opt.param;

        var rootnode = [{
            id: 0,
            text: "root",
            iconCls: "icon2-uityperoot",
            title: {
                ui_type: opt.ui_type,
                ui_mask: ui_mask
            }, children: nodes
        }];

        return rootnode;
    }

    //tree id
    function toNodes($object, param) {
        var opt = options($object);
        var nodes = [];
        if (param.titles === undefined) {
            return nodes;
        }
        for (let i = 0; i < param.titles.length; i++) {
            const title = $.extend({}, param.titles[i]);
            opt.node_id++;
            var node = {
                "id": opt.node_id,
                "text": title.ui_title + '[' + title.name + ']',
                iconCls: "icon2-uitype" + title.ui_type,
                title: title,
            };

            if (typeof (title.ui_mask) == "string") {
                title.ui_mask = JSON.parse(title.ui_mask);
            }

            if (title.ui_type == 17 || title.ui_type == 15 || title.ui_type == 16) {
                var _mask = $.extend({}, title.ui_mask);
                if (_mask.param === undefined) {
                    _mask.param = {};
                    title.ui_mask.param = {};
                }
                var sub_node = toNodes($object, _mask.param);
                delete title.ui_mask.param.titles;
                node.children = sub_node;
                node.state = "closed";
            }

            nodes.push(node);
        }
        return nodes;
    }

    function nodeToTitles(nodes) {
        var titles = [];
        for (let i = 0; i < nodes.length; i++) {
            const title = $.extend({}, nodes[i].title);
            if (title.ui_type == 17 || title.ui_type == 15 || title.ui_type == 16) {
                if (!(nodes[i].children === undefined)) {
                    var sub_titles = { titles: nodeToTitles(nodes[i].children) };
                    if (!(title.ui_mask.param.model === undefined)) {
                        sub_titles.model = title.ui_mask.param.model;
                    }
                    title.ui_mask.param = sub_titles;
                }
            }

            titles.push(title);
        }
        return titles;
    }

    function resize($object, params) {
        var opt = options($object);
        var $uniqueID = $object.attr("id");
        if (typeof params == "object") {
            opt.width = params.width;
            opt.height = params.height;
        }

        opt.$layout.layout("resize", {
            width: opt.width,
            height: opt.height
        });

        var lwidth = opt.$west.width();
        opt.$s_type.combobox("resize", lwidth - 4);

        opt.$div.css({
            width: lwidth,
            height: opt.height - 37,
            overflow: "auto",
            "border-top": "1px solid #efefef"
        });

        var rw = opt.$center.width();
        opt.$tabs.tabs("resize", {
            width: rw,
            height: opt.height
        });
        rw = opt.$center.width();

        var tab = opt.$tabs.tabs('getSelected');
        var tab_index = opt.$tabs.tabs('getTabIndex', tab);
        if (tab_index == 0) {
            opt.$table.yqTitlesEdit("resize", {
                width: rw - 2,
                height: opt.height - 69
            });
        } else if (tab_index == 1) {
            $("#" + $uniqueID + "_jsonview").yqCodeEdit("resize", {
                width: rw,
                height: opt.height - 36
            });
        } else if (tab_index == 2) {
            $("#" + $uniqueID + "_test").yqUnitEdit("resize", {
                width: rw,
                height: opt.height - 36
            });
        }

        if (!(opt.setResizeTime === undefined)) {
            clearInterval(opt.setResizeTime);
            opt.setResizeTime = undefined;
        };
    }

    function destroy($object) {
        var opt = options($object);
        var $uniqueID = $object.attr("id");

        var $div = $("<div></div>")
        $object.before($div);

        opt.$s_type.combobox("destroy");
        opt.$tree.remove();
        opt.$table.yqTitlesEdit("destroy");
        $("#" + $uniqueID + "_jsonview").yqCodeEdit("destroy");

        opt.$txt_type.textbox("destroy");
        opt.$txt_title.textbox("destroy");
        opt.$txt_name.textbox("destroy");
        opt.$save.remove();
        opt.$tabs.remove();
        opt.$layout.remove();

        delete opt.$tree;
        delete opt.$table;

        delete opt.$txt_type;
        delete opt.$txt_title;
        delete opt.$txt_name;
        delete opt.$save;
        delete opt.$tabs;
        delete opt.$layout;

        $object.removeData("virtualedit_opt");
        $object.removeData("yqtype");
        $object.removeClass("layout");

        $object.empty();
        var $new_obj = $($object.prop("outerHTML"));
        $div.before($new_obj);
        $div.remove();
        $object.remove();
    }

    function getValue($object) {
        var opt = options($object);
        var root = opt.$tree.tree('find', 0);
        var titles = nodeToTitles(root.children);

        var ui_mask = $.extend({}, opt.ui_mask);
        ui_mask.ui_type = parseInt(opt.ui_type);
        ui_mask.param = {
            titles: titles,
            model: root.title.ui_mask.param.model
        }
        //console.log(ui_mask);
        return ui_mask;
    }

    function setValue($object, value) {
        var opt = options($object);
        if (value === undefined || value === null) {
            value = {};
        }
        if (typeof value == "string") {
            value = JSON.parse(value);
        }
        var val = $.extend({}, value);
        if (val.param === undefined) {
            opt.param = {
                titles: [],
                model: []
            };
        } else {
            opt.param = val.param;
            delete val.param;
        }
        if (val.ui_type === undefined) {
            opt.ui_type = 17;
        } else {
            opt.ui_type = val.ui_type;
            delete val.ui_type;
        }
        opt.ui_mask = val;

        opt.$txt_type.textbox("setValue", "");
        opt.$txt_title.textbox("setValue", "");
        opt.$txt_name.textbox("setValue", "");
        opt.$table.yqTitlesEdit("clear");

        opt.$s_type.combobox("setValue", opt.ui_type);
        var rootnode = getData($object);
        opt.$tree.tree("loadData", rootnode);
    }
})(jQuery);